﻿using System;
using System.Collections.Generic;
using System.Text;

namespace FySystem.Net.FyNetConnection.Src.SubPacking
{
    public class SubPackingWithInnerMode
    {
        /// <summary>
        /// 按照结束字符来分包
        /// </summary>
        /// <param name="fyServer"></param>
        /// <param name="stateObject"></param>
        internal static List<byte[]> SubPacking(byte[] endFlag, StateObjectBase stateObject)
        {
            List<byte[]> segments = null;
            try
            {
                bool needToSplicMsg = false;

                if (endFlag != null)
                {
                    if (endFlag.Length > 0)
                        needToSplicMsg = true;
                }

                if (needToSplicMsg)
                {
                    List<byte> bytes = new List<byte>();

                    //加入之前未结束的数据
                    if (stateObject.stream != null)
                    {
                        if (stateObject.stream.Length > 0)
                            bytes.AddRange(stateObject.stream);
                    }

                    //加入当前收到的数据
                    if (stateObject.Buffer != null)
                    {
                        if (stateObject.Buffer.Length > 0)
                            bytes.AddRange(stateObject.Buffer);
                    }

                    //对数据进行分段
                    segments = new List<byte[]>();

                    int endFlagMaxIndex = endFlag.Length - 1;
                    int checkedIndex = 0;
                    int segStartIndex = 0;

                    for (int i = 0; i < bytes.Count; i++)
                    {
                        if (bytes[i] == endFlag[checkedIndex])
                        {
                            if (checkedIndex == endFlagMaxIndex)
                            {
                                //表示一段消息已经结束
                                checkedIndex = 0;
                                byte[] seg = new byte[i - endFlag.Length - segStartIndex + 1];
                                bytes.CopyTo(segStartIndex, seg, 0, seg.Length);
                                segments.Add(seg);
                                segStartIndex = i + 1;
                            }
                            else
                            {
                                checkedIndex++;
                            }
                        }
                        else
                            checkedIndex = 0;
                    }

                    if (segStartIndex < bytes.Count)
                    {
                        byte[] parts = new byte[bytes.Count - segStartIndex];
                        bytes.CopyTo(segStartIndex, parts, 0, parts.Length);
                        stateObject.stream = parts;
                    }
                    else
                        stateObject.stream = null;
                }
                else
                {
                    segments = new List<byte[]>();
                    segments.Add(stateObject.Buffer);
                }
            }
            catch (Exception)
            {
                throw;
            }
            return segments;
        }
    }
}
